[小ネタ] シェルスクリプトで日付 ⇔ UNIXTIME 相互変換の計算がしたい(GNU date, Python)
TL;DR
- シェルスクリプトで日付の計算する時には、一回 UNIXTIME を挟むと便利
- GNU date コマンドがあればそれで一発。macOS でも brew で導入可能
- なければ、Python でごにょごにょすればいい
シェルスクリプトで日付の計算がしたい (GNU date)
いまのご時世、例えば 10/31 の 23:00 から 5時間後 のタイムスタンプを計算しようとして、いちから正規表現で文字列を切り出して繰り上がりを計算して。。。ということはもうやりたくないです(挨拶)。
いろんなやり方があると思いますが、なるべく汎用的で手軽に、シェルスクリプトから使える方法で。。。と考えて、最初に思いついたのが GNU date を使うやり方です。-d
オプションで指定すれば、望んだ時点の日付を好きなフォーマットで出力できます。
macOS に標準ではいっている date
コマンドは BSD 版なのですが、brew
を使って coreutils
パッケージをインストールすると使えるようになります(Symlink などで置き換えなければ gdate
という別コマンドになります)。
$ brew install coreutils : $ gdate --version date (GNU coreutils) 8.30 :
実際にやってみます。まず 「10/31 の 23:00 (日本時間)」の UNIXTIME を得ます(Linux 環境などの場合は gdate
を date
に読み替えてください)。
gdate -d '10/31 23:00 JST' -u +%s 1540994400
次に、得られた UNIXTIME の 5時間後を計算します。
unixtime1=$(gdate -d '10/31 23:00 JST' +%s) echo $(( $unixtime1 + 5 * 60 * 60)) # 5x60x60(秒)を加算 1541012400
これを人間が読める書式で出力します。
unixtime1=$(gdate -d '10/31 23:00 JST' +%s) unixtime2=$(( $unixtime1 + 5 * 60 * 60)) gdate -d "@$unixtime2" "+%Y/%m/%d %T" # UNIXTIME 形式の場合は、-d で指定する際に「@」を付ける 2018/11/01 04:00:00
シェルスクリプトで日付の計算がしたい (Python)
gdate
で目的は果たせるのですが、ただこれを社内展開するときに、このためにだけ「macOS のひとは、brew と coreutils インストールしてください」とは言いたくありませんでした。
代替になるもの、と考えて、思いついたのは Python を使うやり方です。
Pyhton なら macOS でも標準で導入されてますし、他の用途でも使うことが多いので大抵あるかと思いました。正直 「全部 Python で書けよ」 と自分にツッコミ入れざるを得ないのですが、せっかくなのであくまで シェルスクリプトで使う ことに拘って書いてみました。
まず日付の文字列から UNIXTIME を得ます。dateutil.parser
モジュールを使ってパースしました。
str='10/31 23:00 JST' cmd=' import dateutil.parser print( dateutil.parser.parse("'"${str}"'").strftime("%s") )' python -c "$cmd" 1540994400
これに 5時間たすところは同じなので省略するとして、UNIXTIME から datetime オブジェクトを生成し、人間が読める書式で出力します。
unixtime1=$(python -c "$cmd") unixtime2=$(( $unixtime1 + 5 * 60 * 60)) cmd=' import datetime print( datetime.datetime.fromtimestamp('${unixtime}').strftime("%Y/%m/%d %T") )' python -c "$cmd" 2018/11/01 04:00:00
同じことができました!
Python 2.7.13 ならびに 3.6.5 の環境で動くことを確認しました。日付計算なんて基本的なことですし、もしかしたらもっとうまいやり方があるかも知れませんが、よければ参考にしてください。